﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using BibMan.model;
using BibMan.model.database.bibtex;
using System.Text.RegularExpressions;
using BibMan.util;
using System.Diagnostics;

namespace BibMan.model.database {
    [Serializable]
    public class Reference : IComparable<Reference>, ICloneable, IXmlSerializable, IIdentifiable<String> {

        private readonly String ID_XML = "Id";
        private readonly String NOTES_XML = "Notes";
        private const String PIN_XML = "Pin";
        private readonly String PATH_XML = "Path";

        public HashSet<String> Pins { get; private set; }
        public BibItem BibItem { get; private set; }
        public String Id {
            get {
                return BibItem.Id;
            }
            set {
                BibItem.Id = value;
            }
        }

        public String Notes { get; set; }
        public String Path { get; set; }

        

        public Reference() {
            this.BibItem = new BibItem();
            this.Pins = new HashSet<String>();
        }
        public Reference(BibItem bibItem) {
            this.BibItem = bibItem;
            this.Pins = new HashSet<String>();
        }

        public override int GetHashCode() {
            return Id.GetHashCode();
        }

        public override bool Equals(object obj) {
            return Id.Equals((obj as Reference).Id);
        }

        public int CompareTo(Reference other) {
            return this.BibItem.CompareTo(other.BibItem);
        }

        public object Clone() {
            Reference ret = new Reference();
            ret.Path = Path;
            ret.Notes = Notes;
            ret.Pins = new HashSet<String>(Pins);
            ret.BibItem = (BibItem)BibItem.Clone();
            return ret;
        }

        public System.Xml.Schema.XmlSchema GetSchema() {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader) {
            if (reader.IsEmptyElement) return;

            XmlSerializer biSerializer = new XmlSerializer(typeof(BibItem));

            String id = reader.GetAttribute(ID_XML);
            reader.ReadToFollowing(PATH_XML);
            Path = reader.ReadElementString(PATH_XML);
            while (reader.LocalName == PIN_XML) {
                Pins.Add(reader.ReadElementString());
            }
            BibItem = (BibItem)biSerializer.Deserialize(reader);
            reader.ReadToFollowing(NOTES_XML);
            Notes = reader.ReadElementString(NOTES_XML);
            this.Id = id;
        }

        public void WriteXml(System.Xml.XmlWriter writer) {
            XmlSerializerNamespaces blankNamespace = new XmlSerializerNamespaces();
            blankNamespace.Add(string.Empty, string.Empty);
            XmlSerializer biSerializer = new XmlSerializer(typeof(BibItem));

            writer.WriteAttributeString(ID_XML, Id);
            writer.WriteElementString(PATH_XML, Path);
            foreach (String pin in Pins) {
                writer.WriteElementString(PIN_XML, pin);
            }
            biSerializer.Serialize(writer, BibItem);
            writer.WriteElementString(NOTES_XML, Notes);
        }
    }
}
